from django.shortcuts import render
from web.forms.file import FileFolderModelForm, FileModelForm
from django.http import JsonResponse, HttpResponse
from django.forms import model_to_dict
from web import models
from utils.tencent.cos import delete_file, delete_file_list, credential
from django.views.decorators.csrf import csrf_exempt
from django.urls import reverse
import json

def file(request, project_id):
    """ 文件列表 & 添加文件夹"""
    parent_object = None
    folder_id = request.GET.get("folder", "")

    if folder_id.isdecimal():  # 判断是否是十进制的数
        parent_object = models.FileRepository.objects.filter(id=int(folder_id), file_type=2,
                                                             project_id=project_id).first()
    if request.method == "GET":
        # 导航条
        bread_crumb_list = []
        parent = parent_object
        while parent:
            # bread_crumb_list.insert(0, {"id": parent.id, "name": parent.name})
            bread_crumb_list.insert(0, model_to_dict(parent, ["id", "name"]))  # 和上面等价
            parent = parent.parent

        # 把当前目录下所有的文件和文件夹全部获取到就行
        queryset = models.FileRepository.objects.filter(project_id=project_id)
        if parent_object:
            # 进入了某目录
            file_object_list = queryset.filter(parent=parent_object).order_by('-file_type')
        else:
            # 根目录的话
            file_object_list = queryset.filter(parent__isnull=True).order_by('-file_type')

        form = FileFolderModelForm(request, parent_object)
        return render(request, "file.html",
                      {"form": form,
                       "file_object_list": file_object_list,
                       "bread_crumb_list": bread_crumb_list,
                       "parent_object": parent_object,
                       })

    # POST 添加文件夹 和 修改文件夹
    # 判断是否携带fid，如果携带fid表示修改，如果不带表示添加
    fid = request.POST.get("fid", '')
    edit_object = None
    if fid.isdecimal():  # 判断是否是十进制
        edit_object = models.FileRepository.objects.filter(
            id=int(fid),
            project_id=project_id,
            file_type=2,
        ).first()
    if edit_object:  # 编辑对象存在
        form = FileFolderModelForm(request, parent_object, data=request.POST, instance=edit_object)
    else:
        form = FileFolderModelForm(request, parent_object, data=request.POST)
    if form.is_valid():
        form.instance.project = request.tracer.project
        form.instance.update_user = request.tracer.user
        form.instance.file_type = 2
        form.instance.parent = parent_object
        form.save()
        return JsonResponse({"status": True, })
    return JsonResponse({"status": False, "error": form.errors})


# GET /manage/6/file/delete/?fid=12
def file_delete(request, project_id):
    """删除文件"""
    fid = request.GET.get("fid")
    # 只是删除了文件 和 文件夹 （是级联删除）
    delete_object = models.FileRepository.objects.filter(
        project_id=project_id,
        id=fid,
    ).first()
    if delete_object.file_type == 1:  # 删除的文件
        # 删除文件（需要对数据库中的文件进行删除，cos文件进行删除，项目已使用的空间需要还回

        # 项目已使用的空间需要还回
        request.tracer.project.use_space -= delete_object.file_size
        request.tracer.project.save()

        # cos文件进行删除
        delete_file(request.tracer.project.bucket,
                    request.tracer.project.region,
                    delete_object.key,
                    )
        # 删除数据库中的文件
        delete_object.delete()
        return JsonResponse({"status": True, })
    # 删除文件（需要对文件夹下的文件，对每个文件都做如下操作：文件进行删除，cos文件进行删除，项目已使用的空间需要还回
    # 找到下面的文件和文件夹，对于文件 进行删除， 文件夹继续往里查
    total_size = 0
    key_list = []

    folder_list = [delete_object, ]
    for folder in folder_list:
        child_list = models.FileRepository.objects.filter(
            project_id=project_id,
            parent=folder,
        ).order_by("-file_type")
        for child in child_list:
            if child.file_type == 2:
                folder_list.append(child)
            else:
                total_size += child.file_size
                # 把所有文件的key放到key_list中
                key_list.append({"Key": child.key})

    # cos批量删除文件
    if key_list:
        delete_file_list(
            request.tracer.project.bucket,
            request.tracer.project.region,
            key_list
        )
    # 归还容量
    if total_size:
        request.tracer.project.use_space -= total_size
        request.tracer.project.save()

    # 删除数据库中的文件
    delete_object.delete()
    return JsonResponse({"status": True, })

@csrf_exempt
def cos_credential(request, project_id):
    """生成临时凭证"""
    # 当文件空间限制,单位是 M
    per_file_limit = request.tracer.price_policy.per_file_size
    # 单项目的空间限制,单位是 G
    total_file_limit = request.tracer.price_policy.project_space
    # 获取要上传的每个文件和大小
    file_list = json.loads(request.body.decode("utf-8"))
    # print(file_list)
    # 做容量限制 单文件和总量
    total_size = 0
    for item in file_list:
        if item["size"] > per_file_limit*1024*1024:
            msg = "单文件大小超出限制(最大：{}M)，文件：{}, 请升级套餐。".format(per_file_limit, item["name"])
            return JsonResponse({"status": False, "error": msg})
        total_size += item["size"]
    # 文件已使用空间 request.tracer.project.use_space
    # 总容量的限制： request.tracer.price_policy.project_space
    if request.tracer.project.use_space + total_size > total_file_limit*1024*1024*1024:
        return JsonResponse({"status": False, "error": "容量超出限制，请升级套餐。"})
    result_dict = credential(request.tracer.project.bucket, request.tracer.project.region)
    return JsonResponse({"status": True, "data": result_dict})  # 将含有临时凭证的结果返回给前端的data

@csrf_exempt
def file_post(request, project_id):
    """将上传成功的文件写到数据库"""
    print(request.POST)
    form = FileModelForm(request, data=request.POST)
    # print(form.cleaned_data)
    print("***********")
    print(form.is_valid())
    if form.is_valid():
        data_dict = form.cleaned_data
        print(data_dict)
        # 踢出etag字段
        # data_dict.pop("etag")
        # 添加project，update_user，file_type字段
        data_dict.update({"project": request.tracer.project,
                          "update_user": request.tracer.user,
                          "file_type": 1})
        instance = models.FileRepository.objects.create(**data_dict)

        result = {
            "id": instance.id,
            "name": instance.name,
            "file_size": instance.file_size,
            "username": instance.update_user.username,
            "datetime": instance.update_datetime.strftime("%Y年%m月%d日 %H:%M"),
            "download_url":reverse("web:manage:file_download", kwargs={"project_id":project_id, "file_id": instance.id})
            # "file_type":instance.get_file_type_display()
        }
        return JsonResponse({"status": True, "data": result})
    # 把获取到的数据写入到数据库即可

    return JsonResponse({"status": False, "error": "上文件失败"})


def file_download(request, project_id, file_id):
    """下载文件"""

    # 打开文件获取文件内容，去cos中获取
    import requests
    file_object = models.FileRepository.objects.filter(
        project_id=project_id,
        id=file_id,
    ).first()
    res = requests.get(file_object.file_path)
    data = res.content
    response = HttpResponse(data)
    # 添加响应头
    response["Content-Disposition"] = "attachment;filename={}".format(file_object.name)

    return response








